import nci60.data.connected.LeadingProtein
import nci60.data.maxquant.Project

//specify the directory in which the supplementary files will be created
def outputPath = 'some/directory/'

println 'start'
//projects[ProjectId][ProjectName]
def projects = [:]
//file[ProjectId][File]
def files = [all:(new File(outputPath+'peptides_all.csv'))]
//celllines[ProjectId][CelllineId][CelllineName]
def celllines = [:]
Project.findAll().each{proj->
    projects.put(proj.id, proj.name)
    files.put(proj.id, new File(outputPath+'peptides_'+proj.name+'.csv'))
    celllines.put(proj.id, [:])
}

println 'projects done'

LeadingProtein.executeQuery('select c.currentProject.id, c.id, c.name from Experiment c order by c.name').each{line->
    def proj = line[0]
    def cel = line[1]
    def celName = line[2]
    celllines[proj].put(cel, celName)
}

println 'experiments done'

//data[Sequence].mass=mass(Double)
//              .missedCleavages=missedCleavages(Integer)
//              .uniqProteins=uniqProteins(boolean)
//              .proteins=[Proteins](List<String>)
//              .projects[ProjectId].peptide=PeptideId
//                                  .score=Score(Double)
//                                  .pep=PEP(Double)
//                                  .razor=razor(boolean)
//                                  .uniqGroups=uniqGroups(boolean)
def data = [:]
LeadingProtein.executeQuery('select pip.currentProject.id, pip.protein.mainId, pip.peptide.sequence, pip.peptide.mass, pip.peptide.missedCleavages, pip.peptide.uniqueProteins, pip.peptide.id, pip.peptide.score, pip.peptide.pep, pip.razor, pip.peptide.uniqueGroups from PeptideInProtein pip order by pip.peptide.sequence').each{line->
    def proj = line[0]
    def prot = line[1]
    def seq = line[2]
    def mass = line[3]
    def missedCleavages = line[4]
    def uniqProteins = line[5]
    def pepId = line[6]
    def score = line[7]
    def pep = line[8]
    def razor = line[9]
    def uniqGroups = line[10]
    if(!data.containsKey(seq)){data.put(seq, [mass:mass, missedCleavages:missedCleavages, uniqProteins:uniqProteins, projects:[:], proteins:[]])}
    data[seq].proteins.add(prot)
    data[seq].projects.put(proj, [peptide:pepId, score:score, pep:pep, razor:razor, uniqGroups:uniqGroups])
}

println 'peptides(general) done'

//peptides[ProjectId][PeptideId][CellLineId].intensity=Intensity
//                                          .numberOfEvidences=NumberOfEvidences
//                                          .numberOfUniqueEvidences=NumberOfUniqueEvidences
def peptides = [:]
LeadingProtein.executeQuery('select e.currentProject.id, e.peptide.id, e.experiment.id, e.intensity, e.numberOfEvidences, e.numberOfUniqueEvidences from PeptideExperiment e').each{line->
    def proj = line[0]
    def pepId = line[1]
    def cel = line[2]
    def intensity = line[3]
    def numberOfEvidences = line[4]
    def numberOfUniqueEvidences = line[5]
    if(!peptides.containsKey(proj)){peptides.put(proj, [:])}
    if(!peptides[proj].containsKey(pepId)){peptides[proj].put(pepId, [:])}
    peptides[proj][pepId].put(cel, [intensity:intensity, numberOfEvidences:numberOfEvidences, numberOfUniqueEvidences:numberOfUniqueEvidences])
}

println 'peptides(experiments) done'

//charges[PeptideId][Charges]
def charges = [:]
LeadingProtein.executeQuery('select p.id, c.charge from Peptide p inner join p.charges c').each{line->
    def pepId = line[0]
    def charge = line[1]
    if(!charges.containsKey(pepId)){charges.put(pepId, [])}
    charges[pepId].add(charge)
}

def headline = 'Sequence\tProteins\tMass\tMissed Cleavages\tUnique (Proteins)'
projects.each{proj,projName->
    headline = headline+'\t'+projName+':Charges\t'+projName+':Score\t'+projName+':PEP\t'+projName+':Razor\t'+projName+':Unique (Groups)'
}
projects.each{proj,projName->
    celllines[proj].each{cel, celName->
        headline = headline+'\t'+projName+':'+celName+':Intensity\t'+projName+':'+celName+':Number Of Evidences\t'+projName+':'+celName+':Number Of Unique Evidences'
    }
}
files.all << headline+'\n'
//data[Sequence].mass=mass(Double)
//              .missedCleavages=missedCleavages(Integer)
//              .uniqProteins=uniqProteins(boolean)
//              .proteins=[Proteins](List<String>)
//              .projects[ProjectId].peptide=PeptideId
//                                  .score=Score(Double)
//                                  .pep=PEP(Double)
//                                  .razor=razor(boolean)
//                                  .uniqGroups=uniqGroups(boolean)
data.each{seq,seqData->
    def outline = ''+seq+'\t'+mergeList(seqData.proteins, ',')+'\t'+seqData.mass+'\t'+seqData.missedCleavages+'\t'+seqData.uniqProteins
//            println outline
    projects.each{proj,projName->
        if(seqData.projects.containsKey(proj)){
            outline = outline+'\t'+mergeList(charges[seqData.projects[proj].peptide], ',')+'\t'+seqData.projects[proj].score+'\t'+seqData.projects[proj].pep+'\t'+seqData.projects[proj].razor+'\t'+seqData.projects[proj].uniqGroups
        }else{
            outline = outline+'\t\t\t\t\t'
        }
    }
    projects.each{proj,projName->
        if(seqData.projects.containsKey(proj)){
            celllines[proj].each{cel, celName->
                if(peptides[proj][seqData.projects[proj].peptide].containsKey(cel)){
                    outline = outline+'\t'+peptides[proj][seqData.projects[proj].peptide][cel].intensity+'\t'+peptides[proj][seqData.projects[proj].peptide][cel].numberOfEvidences+'\t'+peptides[proj][seqData.projects[proj].peptide][cel].numberOfUniqueEvidences
                }else{
                    outline = outline+'\t\t\t'
                }
            }
        }else{
            celllines[proj].each{cel, celName->
                outline = outline+'\t\t\t'
            }
        }
    }
    files.all << outline+'\n'
}

println 'writing all_peptides done'

headline = 'Sequence\tProteins\tMass\tMissed Cleavages\tUnique (Proteins)'
projects.each{proj,projName->
    files[proj] << headline
    files[proj] << '\tCharges\tScore\tPEP\tRazor\tUnique (Groups)'
}
projects.each{proj,projName->
    celllines[proj].each{cel, celName->
        files[proj] << '\t'+celName+':Intensity\t'+celName+':Number Of Evidences\t'+celName+':Number Of Unique Evidences'
    }
    files[proj] << '\n'
}
data.each{seq,seqData->
    def outline = ''+seq+'\t'+mergeList(seqData.proteins, ',')+'\t'+seqData.mass+'\t'+seqData.missedCleavages+'\t'+seqData.uniqProteins
    seqData.projects.each{proj,projData->
        files[proj] << outline
        files[proj] << '\t'+mergeList(charges[projData.peptide], ',')+'\t'+projData.score+'\t'+projData.pep+'\t'+projData.razor+'\t'+projData.uniqGroups
        celllines[proj].each{cel, celName->
            if(peptides[proj][projData.peptide].containsKey(cel)){
                files[proj] << '\t'+peptides[proj][seqData.projects[proj].peptide][cel].intensity+'\t'+peptides[proj][seqData.projects[proj].peptide][cel].numberOfEvidences+'\t'+peptides[proj][seqData.projects[proj].peptide][cel].numberOfUniqueEvidences
            }else{
                files[proj] << '\t\t\t'
            }
        }
        files[proj] << '\n'
    }
}

println 'done!!'
